/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Global Trust Authority is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use actix_web::{web, HttpRequest};
use crate::entities::attest_request::AttestRequest;
use crate::strategy::attestation_strategy::AttestationStrategy;
use crate::strategy::attestation_strategy::AttestFuture;
use crate::service::attest_service::DefaultAttestationService;
use crate::chain::attestation_chain::AttestationHandler;
use crate::chain::handlers::{
    NonceValidationHandler,
    NonceProcessingHandler,
    EvidenceVerificationHandler,
    ExportPolicyHandler,
    CustomPolicyHandler,
    EvidenceResponseHandler,
};

pub struct DefaultAttestationStrategy {}

impl DefaultAttestationStrategy {
    pub fn new() -> Self {
        Self {}
    }

    fn create_measurement_chain(&self) -> Box<dyn AttestationHandler> {
        let mut nonce_validation = NonceValidationHandler::new();
        let mut nonce_processing = NonceProcessingHandler::new();
        let mut evidence_verification = EvidenceVerificationHandler::new();
        let mut export_policy = ExportPolicyHandler::new();
        let mut custom_policy = CustomPolicyHandler::new();
        let evidence_response = EvidenceResponseHandler::new();
        
        // Chain the handlers together
        custom_policy.set_next(Box::new(evidence_response));
        export_policy.set_next(Box::new(custom_policy));
        evidence_verification.set_next(Box::new(export_policy));
        nonce_processing.set_next(Box::new(evidence_verification));
        nonce_validation.set_next(Box::new(nonce_processing));
        
        Box::new(nonce_validation)
    }
}

impl AttestationStrategy for DefaultAttestationStrategy {
    fn attest<'a>(&'a self, request: &'a web::Json<AttestRequest>, http_req: &'a HttpRequest) -> AttestFuture<'a> {
        let user_id = http_req.headers().get("User-Id").and_then(|h| h.to_str().ok()).unwrap_or_default().to_string();
        let request_data = (**request).clone();
        Box::pin(async move {
            let chain = self.create_measurement_chain();
            let service = DefaultAttestationService::new();
            service.process_attestation(request_data, user_id, chain).await
        })
    }
}